package org.vectrics.user.web.struts;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.jsp.JspException;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.vectrics.DataException;
import org.vectrics.SystemException;
import org.vectrics.VectricsException;
import org.vectrics.common.util.DateUtil;
import org.vectrics.company.Company;
import org.vectrics.employee.Employee;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.location.Address;
import org.vectrics.location.Location;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.struts.Request;
import org.vectrics.struts.VectricsActionData;
import org.vectrics.struts.VectricsStrutsAction;
import org.vectrics.user.ContactInfo;
import org.vectrics.user.Person;

public abstract class ShowUserEditAction extends VectricsStrutsAction {

    private transient final Logger log = Logger.getLogger(this.getClass());

    public static String NEW_USER_PARAM = "newUser";

    public static String USER_LIST_TYPE_PARAM = "userListClass";

    private UserProfileForm userProfileForm;

    protected abstract UserProfileForm createUserProfileForm();

    protected void loadExtendedData(Request request, UserProfileForm profileForm, Person person)
            throws VectricsException {
        log.info("ShowUserEditAction.loadExtendedData() called.");
    }

    protected void onPersonFound(Request request, Person person) {
    };

    private void storeTypeOfUserListOnSession(Request request) {
        request.setSessionAttribute(USER_LIST_TYPE_PARAM, this.getClass().getName());
    }

    public String doExecute(VectricsActionData actionData) throws JspException {
        log.info("ShowUserEditAction.doExecute() called");
        Request request = actionData.getRequest();
        String forward = "success";

        try {
            log.info("ShowUserEditAction.execute() called.");
            storeTypeOfUserListOnSession(actionData.getRequest());
            UserProfileForm profileForm = null;
            ActionForm form = actionData.getForm();
            if (form != null) {
                log.debug("execute() form exists.");
                profileForm = (UserProfileForm) form;
            }

            if (profileForm == null) {
                log.debug("execute() - creating new UserProfileForm...");
                profileForm = createUserProfileForm();
                form = profileForm;
                actionData.saveForm(form);
            }

            log.debug("execute() - getting user to edit...");
            Person person = getPersonToEdit(actionData.getRequest(), actionData.getAuthPerson());

            String companyId = actionData.getRequest().getParameter("companyId");
            if (person == null) {
                Company company = null;
                if (companyId != null) {
                    company = CoreServiceLocator.getCompanyService().findCompany(new Long(companyId));
                } else {
                    // Provide array for company selection
                    Collection companies = null;
                    Set domains = new HashSet();
                    domains.add(actionData.getAuthDomain());
                    companies = CoreServiceLocator.getCompanyService().findCompaniesForDomains(domains);
                    if (companies.size() == 0) {
                        throw new SystemException("No companies or divisions found that user can add a job to");
                    } else if (companies.size() == 1) {
                        log.debug("Use only company as default");
                        company = (Company) companies.iterator().next();
                        profileForm.setCompanyId(company.getId().toString());
                    } else {
                        forward = "company.select";
                        request.setAttribute("companies", companies);
                        request.setSessionAttribute("companies", companies);
                    }
                    Long idlocationDefault = RecruitServiceLocator.getRecruitConfiguration().getDefaultPersonLocation(
                            company.getDomain());
                    if (idlocationDefault != null) {
                        Location locationDefault = RecruitServiceLocator.getLocationService().findLocation(
                                idlocationDefault);
                        profileForm.setLocation(locationDefault.getName());
                        request.setAttribute("location", idlocationDefault.toString());
                    }
                }
            }

            if (person != null) {
                log.debug("execute() - Populating form properties...  User = " + person.getName());

                profileForm.setUserId(person.getId().toString());
                if (person.getUser() != null) {
                    profileForm.setUserName(person.getUser().getUserName());
                    profileForm.setPassword(person.getUser().getPassword());
                    profileForm.setPassword2(person.getUser().getPassword());
                }
                profileForm.setFirstName(person.getFirstName());
                profileForm.setLastName(person.getLastName());
                profileForm.setPreviousLastName(person.getPreviousLastName());
                profileForm.setMiddleName(person.getMiddleName());
                profileForm.setGender(person.getGender());
                profileForm.setKnownAs(person.getKnownAs());
                profileForm.setMaritalStatus(person.getMaritalStatus());
                profileForm.setPrefix(person.getNamePrefix());

                profileForm.setBirthday(DateUtil.getFechaFormateada(person.getDateOfBirth()));

                if (person.getBirthCountry() != null) {
                    profileForm.setBirthCountry(person.getBirthCountry().getId().toString());
                }

                profileForm.setCuilOrCuit(person.getCuilOrCuit());
                profileForm.setEmergencyContactName(person.getEmergencyContactName());
                profileForm.setEmergencyContactPhoneNumber(person.getEmergencyContactPhoneNumer());
                
                profileForm.setProgrammingLanguage(person.getProgrammingLanguage().name());
                profileForm.setEnglishLevel(person.getEnglishLevel().name());
                
                ContactInfo contact = person.getContactInfo();
                if (contact != null) {
                    log.debug("execute() - contact info found...");

                    profileForm.setEmail(contact.getEmail());
                    if ((contact.getHtmlEmail() != null) && (contact.getHtmlEmail().booleanValue() == false)) {
                        profileForm.setEmailFormat("text");
                    }

                    profileForm.setEmail2(contact.getEmail2());
                    if ((contact.getHtmlEmail2() != null) && (contact.getHtmlEmail2().booleanValue() == false)) {
                        profileForm.setEmailFormat2("text");
                    }

                    if (contact.getCellPhone() != null)
                        profileForm.setCellPhone(contact.getCellPhone().getFormattedNumber());
                    if (contact.getHomePhone() != null)
                        profileForm.setHomePhone(contact.getHomePhone().getFormattedNumber());
                    if (contact.getWorkPhone() != null)
                        profileForm.setWorkPhone(contact.getWorkPhone().getFormattedNumber());
                    if (contact.getAlternatePhone() != null)
                        profileForm.setAlternatePhone(contact.getAlternatePhone().getFormattedNumber());

                    Address homeAddress = contact.getHomeAddress();
                    if (homeAddress != null) {
                        profileForm.setHomeAddress1(homeAddress.getAddress1());
                        profileForm.setHomeAddress2(homeAddress.getAddress2());
                        profileForm.setLocation(homeAddress.getLocation().getId().toString());
                        profileForm.setHomeCountry(homeAddress.getCountryCode());
                        profileForm.setHomeZip(homeAddress.getPostalCode());
                        request.addParameter("location", homeAddress.getLocation().getId().toString());
                        request.addSessionAttribute("location", homeAddress.getLocation().getId().toString());
                        request.setAttribute("location", homeAddress.getLocation().getId().toString());
                        request.setSessionAttribute("location", homeAddress.getLocation().getId().toString());
                    }
                } else {
                    log.debug("execute() - contact info not found");
                }

                // seteo el radio condition
                profileForm.setCondition("n");

                try {
                    loadExtendedData(request, profileForm, person);
                } catch (VectricsException ve) {
                    log.error("VectricsException caught in ShowUserEditAction", ve);
                    throw new JspException("VectricsException caught in ShowUserEditAction", ve);
                }
                onPersonFound(request, person);

                if (log.isDebugEnabled()) {
                    log.debug("ProfileForm.userId = " + profileForm.getUserId());
                    log.debug("ProfileForm.userName = " + profileForm.getUserName());
                    log.debug("ProfileForm.eMail = " + profileForm.getEmail());
                }
            }

            log.debug(" Forwarding to success page");
            saveToken(request.getHttpRequest());
        } catch (DataException de) {
            log.error("DataException getting user information", de);
            throw new JspException("DataException getting user information", de);
        }
        log.info("Forward = " + forward);

        // Si es un Create Person retorna el "success.new"
        String newUserParam = request.getParameter(NEW_USER_PARAM);
        if ((newUserParam == null) || (newUserParam.length() == 0)) {
            newUserParam = (String) request.getAttribute(NEW_USER_PARAM);
        } else {
            if ((newUserParam == null) || (newUserParam.length() > 0)) {
                request.setAttribute(NEW_USER_PARAM, newUserParam);
                forward = "success.new";
            }
            forward = "success.new";
        }
        this.setUserProfileForm(userProfileForm);
        return (forward);
    }

    protected Person getPersonToEdit(Request request, Person authPerson) {
        log.debug("getUserToEdit() - called");

        String newUserParam = request.getParameter(NEW_USER_PARAM);
        if ((newUserParam == null) || (newUserParam.length() == 0))
            newUserParam = (String) request.getAttribute(NEW_USER_PARAM);

        if ((newUserParam == null) || (newUserParam.length() > 0)) {
            request.setAttribute(NEW_USER_PARAM, newUserParam);
        }

        Person person = null;
        String personId = request.getParameter("userId");
        if (personId == null) {
            personId = request.getParameter("user");
        }
        if (personId != null) {
            if (personId.equals("current")) {
                person = ThreadProperties.getPerson();
            } else {
                person = CoreServiceLocator.getPersonService().findPersonById(new Long(personId));
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("getUserToEdit() - personId = " + personId);
        }

        if (newUserParam == null) {
            if (person == null) {
                log.debug("User id was not given and newUser param wasn't specified, editing current user");

                try {
                    person = authPerson;
                } catch (Exception ex) {
                    log.error("Exception finding auth user", ex);
                    throw new DataException("Exception finding auth user", ex);
                }

            }
        }

        return (person);
    }

    public void setUserProfileForm(UserProfileForm userProfileForm) {
        this.userProfileForm = userProfileForm;
    }

    public UserProfileForm getUserProfileForm() {
        return userProfileForm;
    }

    protected Boolean isEmployee(VectricsActionData actionData) {
        String userId = actionData.getRequest().getParameter("userId");

        if ((userId == null) || (userId.trim().length() == 0)) {
            userId = (String) actionData.getRequest().getAttribute("userId");
        }
        if ((userId == null) || (userId.trim().length() == 0)) {
            userId = (String) actionData.getRequest().getSession().getAttribute("userId");
        }
        if ((userId == null) || (userId.trim().length() == 0)) {
            userId = actionData.getRequest().getParameter("id");
        }
        if ((userId == null) || (userId.trim().length() == 0)) {
            userId = actionData.getRequest().getParameter("personId");
        }
        if ((userId == null) || (userId.trim().length() == 0)) {
            userId = (String) actionData.getRequest().getAttribute("personId");
        }
        if ((userId != null) && (userId.equals("current"))) {
            userId = ThreadProperties.getPerson().getId().toString();
        }
        String personId = userId;
        if ((userId == null) || (userId.trim().length() == 0)) {
            throw new RuntimeException("User ID is blank or null");
        }

        String companyId = ThreadProperties.getDomain().getPrimaryCompany().getId().toString();

        // Busco el empleado de la compania.
        Employee employee = RecruitServiceLocator.getCompanyService().findEmployee(new Long(personId),
                new Long(companyId));
        return (employee != null);
    }

}
